#include "CF.h"
#include "CF_WorkspaceManager.h"

#include <QDir>
#include <QFile>
#include <QDomDocument>

#include "pugixml.hpp"

CL_SINGLETON_INIT(CF_WorkspaceManager);

using namespace pugi;

CF_WorkspaceManager::CF_WorkspaceManager()
{
}

CF_WorkspaceManager::~CF_WorkspaceManager()
{
	clear();
}

void CF_WorkspaceManager::clear()
{
	m_projName.clear();
	m_projPath.clear();

	for(std::vector<CE_Scene*>::iterator it=m_scenes.begin(); it!=m_scenes.end(); it++)
	{
		delete *it;
	}
}

bool CF_WorkspaceManager::createProject(const QString& name, const QString& path)
{
	CF_ASSERT(!isLoaded(), "Workspace is already created");

	m_projName = name;
	m_projPath = path;

	return true;
}

CE_Scene* CF_WorkspaceManager::createScene(const QString& name, const QString& fileName)
{
	CF_ASSERT(isLoaded(), "Workspace is not created");
	CF_ASSERT(getSceneByName(name)==NULL, "Scene exist");

	CE_Scene* newScene = new CE_Scene;
	newScene->setSceneName(name.toStdString().c_str());
	m_scenes.push_back(newScene);

	return newScene;
}

CE_Scene* CF_WorkspaceManager::getSceneByName(const QString& sceneName)
{
	for(std::vector<CE_Scene*>::iterator it = m_scenes.begin(); it!=m_scenes.end(); it++)
	{
		CE_Scene* node = (*it);
		if(node->sceneName()==sceneName)
			return node;
	}
	return NULL;
}

bool CF_WorkspaceManager::load(const QString& filePath)
{
	CF_ASSERT(!isLoaded(), "Workspace is already created");

	xml_document xml;
	xml_parse_result result = xml.load_file(filePath.toStdString().c_str());
	if(!result)
		return false;

	xpath_node projectNode = xml.select_single_node(CF_XPATH_PROJECT);
	if(!projectNode)
		return false;
	xml_attribute nameAttr = projectNode.node().attribute(CF_ATTR_NAME);
	if(!nameAttr)
		return false;
	const char* projectName = nameAttr.value();

	QFileInfo fileInfo(filePath);
	bool ret = this->createProject(tr(projectName), fileInfo.path());

	xpath_node_set sceneNodes = xml.select_nodes(CF_XPATH_SCENE);
	for(xpath_node_set::const_iterator it = sceneNodes.begin(); it!=sceneNodes.end(); it++)
	{
		xpath_node sceneNode = *it;
		this->createScene(
			sceneNode.node().attribute(CF_ATTR_NAME).value(),
			sceneNode.node().attribute(CF_ATTR_FILE).value()
		);
	}

	return ret;
}

QString CF_WorkspaceManager::makeWorkspaceFilePath()
{
	return getProjectPath() + tr("/") + getProjectName() + tr(".") + tr(CF_WORKSPACE_FILE_EXT);
}

bool CF_WorkspaceManager::save()
{
	CF_ASSERT(isLoaded(), "Workspace is not created");

	xml_document xml;
	
	xml_node rootNode = xml.append_child(CF_TAG_COCOSFACTORY);
	rootNode.append_attribute("xmlns:" CF_WORKSPACE_NS) = CF_WORKSPACE_URI;

	xml_node workspaceNode = rootNode.append_child(CF_WORKSPACE_NS ":" CF_TAG_WORKSPACE);
	workspaceNode.append_attribute(CF_ATTR_VERSION) = "1.0";

	xml_node projectNode = workspaceNode.append_child(CF_WORKSPACE_NS ":" CF_TAG_PROJECT);
	projectNode.append_attribute(CF_ATTR_NAME) = getProjectName().toStdString().c_str();

	xml_node sceneGroupNode = projectNode.append_child(CF_WORKSPACE_NS ":" CF_TAG_SCENE_GROUP);
	for(std::vector<CE_Scene*>::iterator it = m_scenes.begin(); it!=m_scenes.end(); it++)
	{
		CE_Scene* node = (*it);
		xml_node sceneNode = sceneGroupNode.append_child(CF_WORKSPACE_NS ":" CF_TAG_SCENE);
		sceneNode.append_attribute(CF_ATTR_NAME) = node->sceneName();
		sceneNode.append_attribute(CF_ATTR_FILE) = (tr(node->sceneName()) + "." CF_SCENE_FILE_EXT).toStdString().c_str();
		
//		node->save();
	}

	QDir newWorkspaceDir(getProjectPath());
	if(!newWorkspaceDir.exists())
		newWorkspaceDir.mkpath(".");
	return xml.save_file(makeWorkspaceFilePath().toStdString().c_str());
}
